package pub.cleangao.memm.transport.socket;

import lombok.extern.slf4j.Slf4j;
import pub.cleangao.memm.registry.RpcRuntime;
import pub.cleangao.memm.transport.RpcServer;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;


@Slf4j
public class SocketRpcServer implements RpcServer {

    private final int CPU_CORE_NUM = Runtime.getRuntime().availableProcessors();
    private final ExecutorService threadPool = new ThreadPoolExecutor(CPU_CORE_NUM, CPU_CORE_NUM * 2, 1L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(100 * CPU_CORE_NUM), new ThreadPoolExecutor.CallerRunsPolicy());
    private Socket socket;

    public void start() {
        try (ServerSocket server = new ServerSocket()) {
            String host = InetAddress.getLocalHost().getHostAddress();
            server.bind(new InetSocketAddress(host, RpcRuntime.getConfigProperties().getPort()));
            while ((socket = server.accept()) != null) {
                threadPool.execute(new SocketRpcRequestHandler(socket));
            }
            threadPool.shutdown();
        } catch (IOException e) {
            log.error("socket IO exception:", e);
        }
    }

    @Override
    public void close() {
        try {
            socket.close();
            threadPool.shutdown();
        } catch (IOException ignore) {

        }
    }

}
